/**
 * @name MarkdownEditor
 * @description 带图片上传功能的'掘金'主题 markdown 编辑器
 * @author darcrand
 */

import React, { useMemo } from 'react'
import { Editor } from '@bytemd/react'
import editor_zh from 'bytemd/lib/locales/zh_Hans.json'

// 下划线/todo任务/标题 插件
import gfm from '@bytemd/plugin-gfm'
import gfm_zh from '@bytemd/plugin-gfm/lib/locales/zh_Hans.json'

// 代码高亮
import hljs from 'highlight.js'
import 'highlight.js/styles/atom-one-dark.css'

// 表情包
import gemoji from '@bytemd/plugin-gemoji'

// 由于 编辑器的 展示组件:Viewer 无法添加id, 自己写一个
import marked from 'marked'

import { sleep } from '@/utils'

// 编辑器默认样式,按钮工具等
import './editor-default.css'
// 编辑器内容编辑区域使用掘金主题
import './editor-juejin-theme.css'
// 编辑器展示区样式
import './markdown-viewer.css'

import styles from './styles.module.less'

// 自定义编辑器的代码高亮插件(官方的插件有bug)
function highlight() {
  return {
    viewerEffect({ markdownBody }) {
      markdownBody.querySelectorAll('pre code').forEach((block) => {
        hljs.highlightBlock(block)
      })
    },
  }
}

export const plugins = [gfm({ locale: gfm_zh }), highlight(), gemoji()]

const MarkdownEditor = ({ value = '', onChange, height = 300 }) => {
  const onSelectFiles = useMemo((files = []) => {
    return async function () {
      if (!files || files.length === 0) {
        return
      }
      try {
        await sleep(1000)

        // 上传接口
        // await [imgs=[]]= await upload(files)
        const imgs = [
          {
            url: 'https://sf3-scmcdn2-tos.pstatp.com/xitu_juejin_web/img/logo.a7995ad.svg',
            alt: '图片描述信息',
            title: '图片标题',
          },
        ]

        return imgs
      } catch (err) {
        throw new Error(err)
      }
    }
  }, [])

  return (
    <div className={styles.container} style={{ height }}>
      <Editor
        locale={editor_zh}
        editorConfig={{ tabSize: 2 }}
        value={value}
        plugins={plugins}
        onChange={onChange}
        uploadImages={onSelectFiles}
      />
    </div>
  )
}

marked.setOptions({
  renderer: new marked.Renderer(),
  highlight: function (code, language) {
    const validLanguage = hljs.getLanguage(language) ? language : 'plaintext'
    return hljs.highlight(validLanguage, code).value
  },
  pedantic: false,
  gfm: true,
  breaks: false,
  sanitize: false,
  smartLists: true,
  smartypants: false,
  xhtml: false,
})

export const MarkdownViewer = ({ value = '' }) => {
  const html = useMemo(() => {
    return marked(value)
  }, [value])

  return <div className='markdown-body' dangerouslySetInnerHTML={{ __html: html }}></div>
}

export default MarkdownEditor
